package io.jpress.module.test.controller;

import com.jfinal.aop.Inject;
import com.jfinal.kit.Ret;
import com.jfinal.plugin.activerecord.Page;
import io.jboot.utils.StrUtil;
import io.jboot.web.controller.annotation.RequestMapping;
import io.jboot.web.validate.EmptyValidate;
import io.jboot.web.validate.Form;
import io.jpress.JPressConsts;
import io.jpress.commons.layer.SortKit;
import io.jpress.core.menu.annotation.AdminMenu;
import io.jpress.core.template.Template;
import io.jpress.core.template.TemplateManager;
import io.jpress.model.Menu;
import io.jpress.model.Role;
import io.jpress.model.User;
import io.jpress.module.test.TestFields;
import io.jpress.module.test.model.Test;
import io.jpress.module.test.model.TestCategory;
import io.jpress.module.test.model.TestComment;
import io.jpress.module.test.service.TestCategoryService;
import io.jpress.module.test.service.TestCommentService;
import io.jpress.module.test.service.TestService;
import io.jpress.service.MenuService;
import io.jpress.service.UserService;
import io.jpress.web.base.AdminControllerBase;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.List;
import java.util.Set;

/**
 * Created by black on 2019/3/9.
 */
@RequestMapping(value = "/admin/test", viewPath = JPressConsts.DEFAULT_ADMIN_VIEW)
public class _TestController extends AdminControllerBase {

    @Inject
    private TestService testService;
    @Inject
    private TestCategoryService categoryService;
    @Inject
    private TestCommentService commentService;
    @Inject
    private MenuService menuService;
    @Inject
    private UserService userService;

    @AdminMenu(text = "文章审核", groupId = "test", order = 0)
    public void index(){
        String status = getPara("status");
        String title = getPara("title");
        Long categoryId = getParaToLong("categoryId");

        /*User user = getLoginedUser();

        List<TestCategory> categories = categoryService.findListByUserId(user.getId(), TestCategory.TYPE_CATEGORY);
        SortKit.toLayer(categories);
        setAttr("categories", categories);

        flagCheck(categories, categoryId);

        TestCategory testCategory = categories.get(0);
        categoryId = testCategory.getId();*/
        Page<Test> page = new Page<Test>();
        /*if(categoryId != null){*/
            page = StringUtils.isBlank(status)
                    ? testService._paginateWithoutTrash(getPagePara(), 10, title, categoryId)
                    : testService._paginateByStatus(getPagePara(), 10, title, categoryId, status);
        /*}*/

        setAttr("page", page);

        int draftCount = testService.findCountByStatus(Test.STATUS_DRAFT);
        int trashCount = testService.findCountByStatus(Test.STATUS_TRASH);
        int normalCount = testService.findCountByStatus(Test.STATUS_NORMAL);
        setAttr("draftCount", draftCount);
        setAttr("trashCount", trashCount);
        setAttr("normalCount", normalCount);
        setAttr("totalCount", draftCount + trashCount + normalCount);

//        categoryService

        render("test/test_list.html");
    }

    @AdminMenu(text = "信息发布", groupId = "test", order = 1)
    public void write() {
        List<TestCategory> categories = categoryService.findListByType(TestCategory.TYPE_CATEGORY);
        SortKit.toLayer(categories);
        setAttr("categories", categories);

        setAttr("fields", TestFields.me());


        int testId = getParaToInt(0, 0);

        Test test = null;
        if (testId > 0) {
            test = testService.findById(testId);
            if (test == null) {
                renderError(404);
                return;
            }
            setAttr("test", test);

            List<TestCategory> tags = categoryService.findTagListByTestId(testId);
            setAttr("tags", tags);

            Long[] categoryIds = categoryService.findCategoryIdsByTestId(testId);
            flagCheck(categories, categoryIds);
        }

        String editMode = test == null ? getCookie(JPressConsts.COOKIE_EDIT_MODE) : test.getEditMode();
        setAttr("editMode", JPressConsts.EDIT_MODE_MARKDOWN.equals(editMode)
                ? JPressConsts.EDIT_MODE_MARKDOWN
                : JPressConsts.EDIT_MODE_HTML);

        initStylesAttr("test_");
        render("test/test_write.html");
    }

    @AdminMenu(text = "分类", groupId = "test", order = 2)
    public void category() {
        List<TestCategory> categories = categoryService.findListByType(TestCategory.TYPE_CATEGORY);
        SortKit.toLayer(categories);
        setAttr("categories", categories);

        List<User> userList = userService.findAll();

        setAttr("userList", userList);

        int id = getParaToInt(0, 0);
        if (id > 0) {
            for (TestCategory category : categories) {
                if (category.getId() == id) {
                    setAttr("category", category);
                }
            }
        }
        initStylesAttr("artlist_");
        render("test/category_list.html");
    }

    @AdminMenu(text = "标签", groupId = "test", order = 4)
    public void tag() {
        Page<TestCategory> page = categoryService.paginateByType(getPagePara(), 10, TestCategory.TYPE_TAG);
        setAttr("page", page);

        int id = getParaToInt(0, 0);
        if (id > 0) {
            setAttr("category", categoryService.findById(id));

        }

        initStylesAttr("artlist_");
        render("test/tag_list.html");
    }

    @AdminMenu(text = "评论", groupId = "test", order = 5)
    public void comment() {

        String status = getPara("status");
        String key = getPara("keyword");
        Long testId = getParaToLong("testId");

        Page<TestComment> page =
                StrUtil.isBlank(status)
                        ? commentService._paginateWithoutTrash(getPagePara(), 10, testId, key)
                        : commentService._paginateByStatus(getPagePara(), 10, testId, key, status);

        setAttr("page", page);

        long unauditedCount = commentService.findCountByStatus(TestComment.STATUS_UNAUDITED);
        long trashCount = commentService.findCountByStatus(TestComment.STATUS_TRASH);
        long normalCount = commentService.findCountByStatus(TestComment.STATUS_NORMAL);

        setAttr("unauditedCount", unauditedCount);
        setAttr("trashCount", trashCount);
        setAttr("normalCount", normalCount);
        setAttr("totalCount", unauditedCount + trashCount + normalCount);

        render("test/comment_list.html");
    }

    private void initStylesAttr(String prefix) {
        Template template = TemplateManager.me().getCurrentTemplate();
        if (template == null){
            return;
        }
        List<String> styles = template.getSupportStyles(prefix);
        if (styles != null && !styles.isEmpty()) {
            setAttr("styles", styles);
        }
    }

    private void flagCheck(List<TestCategory> categories, Long... checkIds) {
        if (checkIds == null || checkIds.length == 0
                || categories == null || categories.size() == 0) {
            return;
        }

        for (TestCategory category : categories) {
            for (Long id : checkIds) {
                if (id != null && id.equals(category.getId())) {
                    category.put("isCheck", true);
                }
            }
        }
    }

    @EmptyValidate({
            @Form(name = "test.title", message = "标题不能为空"),
            @Form(name = "test.content", message = "文章内容不能为空")
    })
    public void doWriteSave() {

        Test test = getModel(Test.class, "test");

        if (!validateSlug(test)) {
            renderJson(Ret.fail("message", "slug不能全是数字且不能包含字符：- "));
            return;
        }


        if (StrUtil.isNotBlank(test.getSlug())) {
            Test slugTest = testService.findFirstBySlug(test.getSlug());
            if (slugTest != null && slugTest.getId().equals(test.getId()) == false) {
                renderJson(Ret.fail("message", "该slug已经存在"));
                return;
            }
        }

        long id = (long) testService.saveOrUpdate(test);
        testService.doUpdateCommentCount(id);

        setAttr("testId",id);
        setAttr("test",test);

        Long[] categoryIds = getParaValuesToLong("category");
        Long[] tagIds = getTagIds(getParaValues("tag"));

        Long[] allIds = ArrayUtils.addAll(categoryIds, tagIds);

        testService.doUpdateCategorys(id, allIds);

        if (allIds != null && allIds.length > 0) {
            for (Long categoryId : allIds) {
                categoryService.updateCount(categoryId);
            }
        }

        Ret ret = id > 0 ? Ret.ok().set("id", id) : Ret.fail();
        renderJson(ret);
    }

    private Long[] getTagIds(String[] tags) {
        if (tags == null || tags.length == 0) {
            return null;
        }

        List<TestCategory> categories = categoryService.doNewOrFindByTagString(tags);
        long[] ids = categories.stream().mapToLong(value -> value.getId()).toArray();
        return ArrayUtils.toObject(ids);
    }

    public void doAddCategoryToMenu() {

        Long id = getIdPara();

        TestCategory category = categoryService.findById(id);
        if (category == null) {
            renderJson(Ret.fail().set("message", "该数据已经被删除"));
            return;
        }

        Menu menu = new Menu();
        menu.setPid(0l);
        menu.setUrl(category.getUrl());
        menu.setText(category.getTitle());
        menu.setType(io.jpress.model.Menu.TYPE_MAIN);
        menu.setRelativeTable("test_category");
        menu.setRelativeId(id);
        menu.setOrderNumber(9);

        menuService.saveOrUpdate(menu);

        renderOkJson();
    }


    @EmptyValidate({
            @Form(name = "category.title", message = "分类名称不能为空"),
            @Form(name = "category.slug", message = "slug 不能为空")
    })
    public void doCategorySave() {
        TestCategory category = getModel(TestCategory.class, "category");
        if (!validateSlug(category)) {
            renderJson(Ret.fail("message", "slug不能全是数字且不能包含字符：- "));
            return;
        }

        Object id = categoryService.saveOrUpdate(category);
        categoryService.updateCount(category.getId());

        List<Menu> menus = menuService.findListByRelatives("test_category",id);
        if (menus != null) {
            for (Menu menu : menus) {
                menu.setUrl(category.getUrl());
                menu.setText(category.getTitle());
                menuService.update(menu);
            }
        }

        renderOkJson();
    }

    @EmptyValidate({
            @Form(name = "category.title", message = "标签名称不能为空"),
    })
    public void doTagSave() {
        TestCategory category = getModel(TestCategory.class, "category");
        //标签管理页面添加的标签没有slug，无法显示对应标签下的文章列表 wanghui 2018.11.7
        category.setSlug(category.getTitle());
        if (!validateSlug(category)) {
            renderJson(Ret.fail("message", "slug不能全是数字且不能包含字符：- "));
            return;
        }

        categoryService.saveOrUpdate(category);
        categoryService.updateCount(category.getId());
        renderOkJson();
    }

    public void doCategoryDel() {
        categoryService.deleteById(getIdPara());
        renderOkJson();
    }

    /**
     * 评论回复 页面
     */
    public void commentReply() {
        long id = getIdPara();
        TestComment comment = commentService.findById(id);
        setAttr("comment", comment);
        render("test/comment_reply.html");
    }

    /**
     * 评论编辑 页面
     */
    public void commentEdit() {
        long id = getIdPara();
        TestComment comment = commentService.findById(id);
        setAttr("comment", comment);
        render("test/comment_edit.html");
    }

    public void doCommentSave() {
        TestComment comment = getBean(TestComment.class, "comment");
        commentService.saveOrUpdate(comment);
        renderOkJson();
    }


    /**
     * 进行评论回复
     */
    public void doCommentReply(String content, Long testId, Long pid) {
        User user = getLoginedUser();

        TestComment comment = new TestComment();
        comment.setContent(content);
        comment.setUserId(user.getId());
        comment.setStatus(TestComment.STATUS_NORMAL);
        comment.setTestId(testId);
        comment.setPid(pid);

        commentService.save(comment);
        renderOkJson();
    }


    /**
     * 删除评论
     */
    public void doCommentDel() {
        Long id = getParaToLong("id");
        commentService.deleteById(id);
        renderOkJson();
    }


    /**
     * 批量删除评论
     */
    @EmptyValidate(@Form(name = "ids"))
    public void doCommentDelByIds() {
        Set<String> idsSet = getParaSet("ids");
        render(commentService.deleteByIds(idsSet.toArray()) ? OK : FAIL);
    }


    /**
     * 批量审核评论
     */
    @EmptyValidate(@Form(name = "ids"))
    public void doCommentAuditByIds() {
        Set<String> idsSet = getParaSet("ids");
        render(commentService.batchChangeStatusByIds(TestComment.STATUS_NORMAL, idsSet.toArray()) ? OK : FAIL);
    }


    /**
     * 修改评论状态
     */
    public void doCommentStatusChange(Long id, String status) {
        render(commentService.doChangeStatus(id, status) ? OK : FAIL);
    }

    @AdminMenu(text = "设置", groupId = "test", order = 6)
    public void setting() {
        render("test/setting.html");
    }


    public void doDel() {
        Long id = getIdPara();
        render(testService.deleteById(id) ? OK : FAIL);
    }

    @EmptyValidate(@Form(name = "ids"))
    public void doDelByIds() {
        Set<String> idsSet = getParaSet("ids");
        render(testService.deleteByIds(idsSet.toArray()) ? OK : FAIL);
    }


    public void doTrash() {
        Long id = getIdPara();
        render(testService.doChangeStatus(id, Test.STATUS_TRASH) ? OK : FAIL);
    }

    public void doDraft() {
        Long id = getIdPara();
        render(testService.doChangeStatus(id, Test.STATUS_DRAFT) ? OK : FAIL);
    }

    public void doNormal() {
        Long id = getIdPara();
        render(testService.doChangeStatus(id, Test.STATUS_NORMAL) ? OK : FAIL);
    }

}
